package
{
	import BlackJack.Model.Events.TableEvent;
	import BlackJack.Model.Events.TableListEvent;
	import BlackJack.Model.VO.DealPoker;
	import BlackJack.Model.VO.MultiClass;
	import BlackJack.Model.VO.Player;
	import BlackJack.Model.VO.RoleClass;
	import BlackJack.Model.VO.TableData;
	import BlackJack.View.Debug;
	import BlackJack.View.Lobby;
	import BlackJack.View.Table;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.Endian;
	import flash.utils.Timer;
	import flash.utils.clearTimeout;
	import flash.utils.setInterval;
	import flash.utils.setTimeout;

	public class FGS12Processer extends FGS12Client
	{
		public var main:BlackJackMain;

		public function FGS12Processer(root:BlackJackMain, dump:Boolean = false)
		{
			super(dump);
			main = root;
			listen(onEcho);
		}

		public function onEcho(type:String, message:String):void
		{
			switch (type)
			{
				case CONNECT_SUCCESS:
				{
					log(type);
					log('C2S_EngineerLogin' + '\t' + client.ID);
					C2S_EngineerLogin(client.ID);
					//C2S_LoginGame(this.debug.token);
					break;
				}
				case SERVER_CLOSE:
				case CLIENT_CLOSE:
				{
					log(type);
					resetPosition();
					break;
				}
				case ERROR_ORIGINAL:
				{
					log(type);
					log(message);
					resetPosition();
					break;
				}
				case DATA_RECEIVE:
				case DATA_SEND:
				{
					log(type);
					break;
				}
			}
		}

		/**
		 * 	工程模式登入
		 * 	@param option
		 */
		override public function S2C_EngineerLogin(token:String):void
		{
			log('S2C_EngineerLogin');
			log('C2S_LoginGame');
			C2S_LoginGame(token);
		}

		/**
		 *	系統訊息
		 * 	@param msg	訊息內容
		 */
		override public function S2C_SysMessage(msg:String):void
		{
			log('S2C_SysMessage' + '\t' + msg);
		}

		/**
		 * 	對話訊息
		 * 	@param SID
		 * 	@param msg	訊息內容
		 */
		override public function S2C_Talk(SID:int, msg:String):void
		{
			trace(this + '\t' + 'S2C_Talk');
			trace('SID:\t' + SID);
			trace('msg:\t' + msg);
		}

		/**
		 *	語音
		 * 	@param SID
		 * 	@param No
		 */
		override public function S2C_SoundMessage(SID:int, No:int):void
		{
			trace('S2C_SoundMessage');
			trace('SID:\t' + SID);
			trace('No:\t' + No);
		}

		/**
		 *	表情圖案
		 * 	@param SID
		 * 	@param No
		 */
		override public function S2C_ImageMessage(SID:int, No:int):void
		{
			trace('S2C_ImageMessage');
			trace('SID:\t' + SID);
			trace('No:\t' + No);
		}

		/**
		 *	玩家	Delay
		 * 	@param SID
		 * 	@param option
		 */
		override public function S2C_ClientDeley(SID:int, option:int):void
		{
			trace(this + '\t' + 'S2C_ClientDeley');
			trace('SID:\t' + SID);
			trace('option:\t' + option);
		}

		/**
		 *	開始讀秒
		 * 	@param Times	秒數
		 */
		override public function S2C_ClientTime(Times:int):void
		{
			trace('S2C_ClientTime');
			trace('Times:\t' + Times);
		}

		/**
		 *	初始化該局遊戲
		 * 	@param SID
		 * 	@param ID
		 * 	@param Option
		 */
		override public function S2C_InitGame(SID:int, ID:String, Option:String):void
		{
			log('S2C_InitGame');
		}

		/**
		 *	同步玩家	SID
		 * 	@param Option
		 */
		override public function S2C_StartUp(Option:String):void
		{
			log('S2C_StartUp');
			C2S_TablegetList(0, 0);
		}

		/**
		 *	載入進度
		 * 	@param Total
		 * 	@param SID
		 * 	@param Pos
		 */
		override public function S2C_LoadingPos(Total:int, SID:Array, Pos:Array):void
		{
			trace('S2C_LoadingPos');
			trace('Total:\t' + Total);
			trace('SID:\t' + SID);
			trace('Pos:\t' + Pos);
		}

		/**
		 *	目前輪到的玩家
		 * 	@param SID
		 */
		override public function S2C_NowPlayer(SID:int):void
		{
			trace('S2C_NowPlayer');
			trace('SID:\t' + SID);
		}

		/**
		 *	遊戲結束
		 */
		override public function S2C_GameOver():void
		{
			trace('S2C_GameOver');
		}

		/**
		 *	有玩家斷線
		 * 	@param SID
		 */
		override public function S2C_UserDisconnect(SID:int):void
		{
			trace('S2C_UserDisconnect');
			trace('SID:\t' + SID);
		}

		/**
		 *	玩家資訊
		 *	@param SID
		 * 	@param Option
		 */
		override public function S2C_PlayerInfo(SID:int, Option:String):void
		{
			var temp:Player = Player.Parse(Option);
			//log('S2C_PlayerInfo' + '\t' + temp.ID);
			if (main.client.ID == temp.ID)
			{
				main.updateClient(temp);
			}
		}

		/**
		 *	該局遊戲結束
		 * 	@param Option
		 *
		 * 	此接口 Server 端未使用
		 */
		override public function S2C_RoundEnd(Option:String):void
		{
			trace('S2C_RoundEnd');
			trace('Option:\t' + Option);
		}

		/**
		 *	結算畫面
		 * 	@param Option
		 */
		override public function S2C_Calculation(Option:String):void
		{
			table.S2C_Calculation(Option);
		}

		/**
		 *	其他玩家結算完畢是否繼續
		 * 	@param SID
		 * 	@param ret
		 */
		override public function S2C_CalculationOK(SID:int, ret:int):void
		{
			trace('S2C_Calculation');
			trace('SID:\t' + SID);
			trace('ret:\t' + ret);
		}

		/**
		 *	活動事件
		 * 	@param EventNo	活動編號
		 * 	@param Option	活動參數
		 */
		override public function S2C_EventOption(EventNo:int, Option:int):void
		{
			//log('S2C_EventOption' + '\t' + EventNo + '-' + Option);
			switch (EventNo)
			{
				case 0:
				{
					table.eventWindow.visible = Option == 1 ? true : false;
					break;
				}
				case 1:
				{
					table.Info('Total').text = Option.toString();
					break;
				}
				case 2:
				{
					table.Info('Today').text = Option.toString();
					break;
				}
				case 3:
				{
					table.Info('Win').text = Option.toString();
					break;
				}
				case 4:
				{
					table.lastCount.visible = Option == 1 ? true : false;
					break;
				}
				case 5:
				case 6:
					break;
			}
			////EventNo=0 , Option=1/0 			開啟/關閉 右上積分顯示器     (預設關閉)
			////EventNo=1 , Option=總積分數字    	右上積分顯示器數字
			////EventNo=2 , Option=本日積分數字  	右上積分顯示器數字
			////EventNo=3 , Option=贏牌次數      	右上積分顯示器數字
			////EventNo=4 , Option=1/0 			開啟/關閉 左下角面版開關     (預設關閉)
			////EventNo=5 , Option=1/0 			開啟/關閉 左下角開始按鈕
			////EventNo=6 , Option=剩餘次數		左下角剩餘次數
		}

		/**
		 *	跑馬燈訊息
		 * 	@param Msg	訊息
		 * 	@param Sec	秒數	(0表示循環播放)
		 */
		override public function S2C_LEDMessage(Msg:String, Sec:int):void
		{
			trace('S2C_LEDMessage');
			trace('Msg:\t' + Msg);
			trace('Sec:\t' + Sec);
		}

		/**
		 *	連線彩金
		 * 	@param Bonus	彩金金額
		 */
		override public function S2C_LinkBonus(Bonus:int):void
		{
			////trace(this + '\t' + 'S2C_LinkBonus' + '\t' + Bonus);
			lobby.delayBonus(Bonus);
			table.delayBonus(Bonus);
		}

		/**
		 *	該頁牌桌列表
		 * 	@param Page		頁數
		 * 	@param Option	牌桌資訊
		 */
		override public function S2C_TableList(Page:int, Option:ByteArray, MD5:uint):void
		{
			log('S2C_TableList' + '\t' + Page);
			lobby.md5[Page] = MD5;
			var s:String = loadString2(Option);
			s = BlackJackMain.Trim(s);
			var temp:Array = s.split('[');
			temp.shift();
			var len:int              = temp.length;
			var v:Vector.<TableData> = Vector.<TableData>([]);
			for (var i:int = 0; i < len; i++)
			{
				v.push(TableData.Parse(temp[i]));
			}
			var event:TableListEvent = new TableListEvent(TableListEvent.TableList);
			event.data = v;
			event.page = Page;
			lobby.setTableList(event);
			main.state = BlackJackMain.LOBBY;
		}

		/**
		 *	入桌請求的回覆
		 * 	@param Ret		0/1 => 無法進入/成功進入
		 * 	@param TableNo	桌號
		 * 	@param Pos		玩家位置
		 * 	@param Option	Ret==0 : 錯誤原因 ; Ret==1 : 牌桌初始化封包
		 */
		override public function S2C_TableIntoRet(Ret:int, TableNo:int, Pos:int, Option:ByteArray):void
		{
			log('S2C_TableIntoRet' + '\t' + TableNo + '-' + Pos + ' : ' + Ret);
			var s:String;
			if (Ret == 1)
			{
				table.clearGmae();
				s = BlackJackMain.Trim(loadString2(Option));
				var temp:Array = s.split('[');
				temp.shift();
				table.data = TableData.Parse(temp[0]);
				table.data.spotLight = Pos;
				main.state = BlackJackMain.TABLE;
			}
		}

		/**
		 *	離開牌桌的回覆
		 * 	@param Ret		0/1 => 失敗/成功
		 * 	@param TableNo	桌號
		 */
		override public function S2C_TableExitRet(Ret:int, TableNo:int):void
		{
			log('S2C_TableExitRet' + '\t' + TableNo + '\t' + Ret);
			if (Ret == 1)
			{
				log('C2S_TablegetList' + '\t' + lobby.Page);
				C2S_TablegetList(lobby.Page, lobby.md5[lobby.Page]);
				table.quitGame();
				main.state = BlackJackMain.LOBBY;
			}
		}

		/**
		 *	桌面玩家資訊更新
		 * 	@param Pos			位置
		 * 	@param ID			玩家帳號		空白代表沒人
		 * 	@param Nickname		玩家暱稱
		 * 	@param ModelNo		玩家角色
		 * 	@param State		玩家狀態		0/1/2 => 一般/代打/玩家斷線Server接手
		 */
		override public function S2C_TablePlayerRenew(Pos:uint, ID:String, Nickname:String, ModelNo:uint, State:uint):void
		{
			log('S2C_TablePlayerRenew');
			if (ID.length > 0)
			{
				table.Role(Table.Player + Pos).enable();
				table.Role(Table.Player + Pos).txtName.text = Nickname;
				table.Role(Table.Player + Pos).txtAccount.text = ID;
				table.Role(Table.Player + Pos).setModelNo(ModelNo);
			}
			else
			{
				table.Role(Table.Player + Pos).disable();
			}
		}

		override public function S2C_PleaseBet():void
		{
			table.S2C_PleaseBet();
		}

		/**
		 *	廣播玩家投注
		 * 	@param Pos		玩家位置
		 * 	@param Point	投注金額
		 */
		override public function S2C_PlayerBet(Pos:uint, Point:int):void
		{
			if (table.data.spotLight == Pos)
			{
				return;
			}
			table.Role(Table.Player + Pos).Bet(Point);
		}

		/**
		 *	發牌
		 * 	@param BankPoker	莊家的第一張牌
		 * 	@param Poker1		玩家的第一張牌	length = 5
		 * 	@param Poker2		玩家的第二張牌	length = 5
		 * 	@param PokerPoint1	牌點數總和
		 * 	@param PokerPoint2	牌點數總和
		 */
		override public function S2C_Dealing(BankPoker:uint, Poker1:Array, Poker2:Array, PokerPoint1:Array, PokerPoint2:Array):void
		{
			table.S2C_Dealing(BankPoker, Poker1, Poker2, PokerPoint1, PokerPoint2);
		}

		/**
		 *	第一手詢問
		 * 	@param Deal			先賠
		 * 	@param Insurance	買保險
		 * 	@param Surrender	投降
		 */
		override public function S2C_PlayerAsk1(Deal:uint, Insurance:uint, Surrender:uint):void
		{
			var s:String = 'S2C_PlayerAsk1' + '\t';
			if (Deal == 1)
			{
				s += '先賠' + '\t';
			}
			if (Insurance == 1)
			{
				s += '買保險' + '\t';
			}
			if (Surrender == 1)
			{
				s += '投降' + '\t';
			}
			log(s);
			var dict:Dictionary = new Dictionary();
			dict[TableEvent.Deal] = Deal;
			dict[TableEvent.Insurance] = Insurance;
			dict[TableEvent.Surrender] = Surrender;
			dict[TableEvent.Cancel] = 1;
			table.S2C_PlayerAsk1(dict);
		}

		/**
		 *	先賠
		 * 	@param Pos		位置
		 * 	@param Point	金額
		 */
		override public function S2C_PlayerDeal(Pos:uint, Point:int):void
		{
			message('S2C_PlayerDeal' + '\t' + Pos);
			var s:String = Table.Player + Pos;
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Deal);
		}

		/**
		 *	買保險
		 * 	@param Pos		位置
		 * 	@param Point	金額
		 */
		override public function S2C_PlayerInsurance(Pos:uint, Point:int):void
		{
			message('S2C_PlayerInsurance' + '\t' + Pos);
			var s:String = Table.Player + Pos;
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Insurance);
			table.Role(s).isInsurance = true;
		}

		/**
		 *	投降
		 * 	@param Pos		位置
		 * 	@param Point	金額
		 */
		override public function S2C_PlayerSurrender(Pos:uint, Point:int):void
		{
			message('S2C_PlayerSurrender' + '\t' + Pos);
			var s:String = Table.Player + Pos;
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Surrender);
			//table.Role(s).isSurrender = true;
		}

		/**
		 *	第一手結束
		 */
		override public function S2C_PlayerAsk1End():void
		{
			log('S2C_PlayerAsk1End');
		}

		/**
		 *	第二手詢問
		 * 	@param Pos		位置
		 * 	@param SplitNo	第幾門
		 * 	@param Hit		補牌
		 * 	@param Stay		停牌
		 * 	@param Double	雙倍
		 * 	@param Split	分門
		 */
		override public function S2C_PlayerAsk2(Pos:uint, SplitNo:uint, Hit:uint, Stay:uint, Double:uint, Split:uint):void
		{
			if (table.isDealing)
			{
				setTimeout(S2C_PlayerAsk2, 500, Pos, SplitNo, Hit, Stay, Double, Split);
				return;
			}
			log('S2C_PlayerAsk2' + '\t' + Pos + '-' + SplitNo);
			var s:String = '';
			if (Split == 1)
			{
				s += '分門' + '\t';
			}
			if (Double == 1)
			{
				s += '加倍' + '\t';
			}
			if (Hit == 1)
			{
				s += '補牌' + '\t';
			}
			if (Stay == 1)
			{
				s += '停牌' + '\t';
			}
			log(s)
			var dict:Dictionary = new Dictionary();
			dict[TableEvent.Hit] = Hit;
			dict[TableEvent.Split] = Split;
			dict[TableEvent.Stay] = Stay;
			dict[TableEvent.Double] = Double;
			table.S2C_PlayerAsk2(dict, Pos, SplitNo);
		}

		/**
		 *	補牌
		 * 	@param Pos			位置
		 * 	@param Split		第幾門
		 * 	@param Poker		補的牌
		 * 	@param PokerPoint	牌點數總和
		 */
		override public function S2C_PlayerHit(Pos:uint, Split:uint, Poker:uint, PokerPoint:Array):void
		{
			if (table.isDealing)
			{
				setTimeout(S2C_PlayerHit, 500, Pos, Split, Poker, PokerPoint);
				return;
			}
			message('S2C_PlayerHit' + '\t' + Pos + '-' + Split + '\t' + Poker.toString(16));
			var s:String = Table.Player + Pos;
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Hit);
			table.addDeal(new DealPoker(s, Poker, Split));
		}

		/**
		 *	停牌
		 * 	@param Pos			位置
		 * 	@param Split		第幾門
		 * 	@param PokerPoint	牌點數總和
		 */
		override public function S2C_PlayerStay(Pos:uint, Split:uint, PokerPoint:Array):void
		{
			message('S2C_PlayerStay' + '\t' + Pos + '-' + Split);
			var s:String = Table.Player + Pos;
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Stay);
		}

		/**
		 *	雙倍
		 * 	@param Pos			位置
		 * 	@param Split		第幾門
		 */
		override public function S2C_PlayerDouble(Pos:uint, Split:uint):void
		{
			message('S2C_PlayerDouble' + '\t' + Pos + '-' + Split);
			var s:String = Table.Player + Pos;
			if (Pos == table.data.spotLight)
			{
				table.isNonChangeBet = true;
				table.TotalBet *= 2;
			}
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Double);
			table.Role(s).isDouble = true;
		}

		/**
		 *	分門
		 * 	@param Pos	位置
		 */
		override public function S2C_PlayerSplit(Pos:uint):void
		{
			message('S2C_PlayerSplit' + '\t' + Pos);
			var s:String = Table.Player + Pos;
			if (Pos == table.data.spotLight)
			{
				table.isNonChangeBet = true;
				table.TotalBet *= 2;
			}
			Msg(s).gotoAndStop(1);
			Msg(s).gotoAndStop(TableEvent.Split);
			Role(s).isSplit = true;
		}

		/**
		 *	玩家某副牌結束
		 * 	@param Pos		位置
		 * 	@param Split	分門	0 / 1
		 * 	@param Point	勝負金額	0 = 平手
		 */
		override public function S2C_PlayerCalculation(Pos:uint, Split:uint, Point:int):void
		{
			message('S2C_PlayerCalculation' + '\t' + Pos + '-' + Split + '\t' + Point);
			message('C2S_PlayerCalculationOK');
			C2S_PlayerCalculationOK();
		}

		/**
		 *	莊家補牌
		 * 	@param Poker		補的牌
		 * 	@param PokerPoint	牌點數總和
		 */
		override public function S2C_BankerHit(Poker:uint, PokerPoint:Array):void
		{
			message('S2C_BankerHit' + '\t' + Poker.toString(16));
			table.addDeal(new DealPoker(Table.Banker, Poker));
		}

		/**
		 *	莊家停牌
		 * 	@param PokerPoint	牌點數總和
		 */
		override public function S2C_BankerStay(PokerPoint:Array):void
		{
			message('S2C_BankerStay');
			message('C2S_RoundEndOK');
			setTimeout(C2S_RoundEndOK, 500);
		}

		/**
		 *	中頭彩訊息
		 * 	@param TableNo	桌號
		 * 	@param Pos		位置
		 * 	@param Split	第幾門
		 * 	@param ID		帳號
		 * 	@param Name		暱稱
		 * 	@param Point	點數
		 */
		override public function S2C_GetLinkBonus(TableNo:int, Pos:uint, Split:uint, ID:String, Name:String, Point:int):void
		{
			trace('S2C_GetLinkBonus');
			trace('TableNo:\t' + TableNo);
			trace('Pos:\t' + Pos);
			trace('Split:\t' + Split);
			trace('ID:\t' + ID);
			trace('Name:\t' + Name);
			trace('Point:\t' + Point);
		}

		override public function S2C_DEFCOMM(com:int, p:String):void
		{
		}

		override public function S2C_DEFPing():void
		{
			C2S_DEFPong();
		}

		override public function S2C_DEFPong():void
		{
		}

		private function get client():Player
		{
			return main.client;
		}

		public function get lobby():Lobby
		{
			return main.lobby;
		}

		public function get table():Table
		{
			return main.table;
		}

		private function log(value:String):void
		{
			main.debug.LOG(value);
		}

		private function message(value:String):void
		{
			main.debug.MESSAGE(value);
		}

		private function Role(value:String):RoleClass
		{
			return table.Role(value);
		}

		private function Msg(value:String):MovieClip
		{
			return table.Msg(value);
		}
	}
}
